package yao.config;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import yao.config.exception.ConfigException;
import yao.config.exception.ConfigPathException;


/**
 * 配置对象
 * 
 * @author YaoMing
 */
public class Config {

	private String path;

	private Storage storage;

	private Set<File> files;

	/**
	 * 构造一个配置对象
	 * 
	 * @throws ConfigPathException
	 * @throws ConfigException
	 */
	public Config(String path) throws ConfigException, ConfigPathException {
		this.path = path;
		reload();
	}

	/**
	 * 得到配置的值
	 * 
	 * @param name
	 * @return
	 */
	public Value getValue(String name) {
		return getNode(name).getValue();
	}

	/**
	 * 得到一个String，如果name没有对应的值，将抛出NodeNotFoundException
	 * 
	 * @param name
	 * @return
	 */
	public String getString(String name) {
		return getValue(name).toString();
	}

	/**
	 * 得到一个String，发生异常，将返回默认值
	 * 
	 * @param name
	 * @param defaultValue
	 * @return
	 */
	public String getString(String name, String defaultValue) {
		try {
			return getString(name);
		} catch (Exception e) {
			return defaultValue;
		}
	}

	/**
	 * 得到一个Character，如果name没有对应的值，将抛出NodeNotFoundException
	 * 
	 * @param name
	 * @return
	 */
	public Character getCharacter(String name) {
		return getValue(name).characterValue();
	}

	/**
	 * 得到一个Character，如果发生异常，将返回默认值
	 * 
	 * @param name
	 * @param defaultValue
	 * @return
	 */
	public Character getCharacter(String name, Character defaultValue) {
		try {
			return getCharacter(name);
		} catch (Exception e) {
			return defaultValue;
		}
	}

	/**
	 * 得到一个Long，如果name没有对应的值，将抛出NodeNotFoundException
	 * 
	 * @param name
	 * @return
	 */
	public Long getLong(String name) {
		return getValue(name).longValue();
	}

	/**
	 * 得到一个Long，如果发生异常，将返回默认值
	 * 
	 * @param name
	 * @param defaultValue
	 * @return
	 */
	public Long getLong(String name, Long defaultValue) {
		try {
			return getLong(name);
		} catch (Exception e) {
			return defaultValue;
		}
	}

	/**
	 * 得到一个Long，如果name没有对应的值，将抛出NodeNotFoundException
	 * 
	 * @param name
	 * @return
	 */
	public Double getDouble(String name) {
		return getValue(name).doubleValue();
	}

	/**
	 * 得到一个Double，如果发生异常，将返回默认值
	 * 
	 * @param name
	 * @param defaultValue
	 * @return
	 */
	public Double getDouble(String name, Double defaultValue) {
		try {
			return getDouble(name);
		} catch (Exception e) {
			return defaultValue;
		}
	}

	/**
	 * 得到一个Float，如果name没有对应的值，将抛出NodeNotFoundException
	 * 
	 * @param name
	 * @return
	 */
	public Float getFloat(String name) {
		return getValue(name).floatValue();
	}

	/**
	 * 得到一个Float，如果发生异常，将返回默认值
	 * 
	 * @param name
	 * @param defaultValue
	 * @return
	 */
	public Float getFloat(String name, Float defaultValue) {
		try {
			return getFloat(name);
		} catch (Exception e) {
			return defaultValue;
		}
	}

	/**
	 * 得到一个Integer，如果name没有对应的值，将抛出NodeNotFoundException
	 * 
	 * @param name
	 * @return
	 */
	public Integer getInteger(String name) {
		return getValue(name).integerValue();
	}

	/**
	 * 得到一个Integer，如果发生异常，将返回默认值
	 * 
	 * @param name
	 * @param defaultValue
	 * @return
	 */
	public Integer getInteger(String name, Integer defaultValue) {
		try {
			return getInteger(name);
		} catch (Exception e) {
			return defaultValue;
		}
	}

	/**
	 * 得到一个Short，如果name没有对应的值，将抛出NodeNotFoundException
	 * 
	 * @param name
	 * @return
	 */
	public Short getShort(String name) {
		return getValue(name).shortValue();
	}

	/**
	 * 得到一个Short，如果发生异常，将返回默认值
	 * 
	 * @param name
	 * @param defaultValue
	 * @return
	 */
	public Short getShort(String name, Short defaultValue) {
		try {
			return getShort(name);
		} catch (Exception e) {
			return defaultValue;
		}
	}

	/**
	 * 得到一个Boolean，如果name没有对应的值，将抛出NodeNotFoundException
	 * 
	 * @param name
	 * @return
	 */
	public Boolean getBoolean(String name) {
		return getValue(name).booleanValue();
	}

	/**
	 * 得到一个Boolean，如果发生异常，将返回默认值
	 * 
	 * @param name
	 * @param defaultValue
	 * @return
	 */
	public Boolean getBoolean(String name, Boolean defaultValue) {
		try {
			return getBoolean(name);
		} catch (Exception e) {
			return defaultValue;
		}
	}

	/**
	 * 得到一个Byte，如果name没有对应的值，将抛出NodeNotFoundException
	 * 
	 * @param name
	 * @return
	 */
	public Byte getByte(String name) {
		return getValue(name).byteValue();
	}

	/**
	 * 得到一个Byte，如果发生异常，将返回默认值
	 * 
	 * @param name
	 * @param defaultValue
	 * @return
	 */
	public Byte getByte(String name, Byte defaultValue) {
		try {
			return getByte(name);
		} catch (Exception e) {
			return defaultValue;
		}
	}

	/**
	 * 根据formater格式化字符串，得到一个Date，如果name没有对应的值，将抛出NodeNotFoundException
	 * 
	 * @param name
	 * @param formater
	 * @return
	 */
	public Date getDate(String name, String formater) {
		SimpleDateFormat df = new SimpleDateFormat(formater);
		try {
			return df.parse(getString(name));
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 根据formater格式化字符串，得到一个Date，如果name没有对应的值，将返回默认值
	 * 
	 * @param name
	 * @param formater
	 * @param defaultDate
	 * @return
	 */
	public Date getDate(String name, String formater, Date defaultDate) {
		SimpleDateFormat df = new SimpleDateFormat(formater);
		try {
			return df.parse(getString(name));
		} catch (Exception e) {
			return defaultDate;
		}
	}

	/**
	 * 得到一个File，如果name没有对应的值，将抛出NodeNotFoundException
	 * 
	 * @param name
	 * @return
	 */
	public File getFile(String name) {
		return new File(getString(name));
	}

	/**
	 * 得到一个File，如果name没有对应的值，将返回默认值
	 * 
	 * @param name
	 * @return
	 */
	public File getFile(String name, File defaultFile) {
		try {
			return new File(getString(name));
		} catch (Exception e) {
			return defaultFile;
		}
	}

	/**
	 * 得到Text属性值，如果name没有对应的值，将抛出NodeNotFoundException
	 * 
	 * @param name
	 * @return
	 */
	public String getText(String name) {
		Node n = getNode(name);
		return n.getText();
	}

	/**
	 * 得到一个节点
	 * 
	 * @param name
	 * @return
	 */
	public Node getNode(String name) {
		return storage.getNode(name);
	}

	/**
	 * 得到一批节点<br>
	 * 参数""得到所有一级节点; 参数"*"得到所有节点
	 * 
	 * @param name
	 * @return
	 */
	public List<Node> getNodes(String name) {
		return storage.getNodeList(name);
	}

	/**
	 * 设置属性值<br>
	 * 注意:如果属性节点的final属性为true将无法实现此功能,并抛出异常
	 * 
	 * @param fullname
	 * @param value
	 * @throws ConfigException
	 */
	public void setValue(String name, String value) throws ConfigException {
		storage.setValue(name, value);
	}

	/**
	 * 保存值
	 * 
	 * @throws ConfigException
	 */
	public void save() throws ConfigException {
		XmlSaver saver = new XmlSaver(storage);
		saver.save();
	}

	/**
	 * 重新加载
	 * 
	 * @throws ConfigException
	 * @throws ConfigPathException
	 */
	public void reload() throws ConfigException, ConfigPathException {
		storage = new Storage();
		files = new TreeSet<File>();

		XmlReader xmlReader = new XmlReader(path);
		xmlReader.storage = storage;
		xmlReader.files = files;

		xmlReader.read();
	}

	/**
	 * 保存并重新加载
	 * 
	 * @throws ConfigException
	 * @throws ConfigPathException
	 */
	public void saveAndReload() throws ConfigException, ConfigPathException {
		save();
		reload();
	}
}
